順便tag今天的課程說現在的講師太混,那也真的是太對不起你們和其他講者了
ps: 在console命令列中輸入?指令,可以看到該指令詳細的說明,例如?rbind,這時候就會出現相關的資料。 在console命令列中輸入example(指令),變可以看到該指令用法,例如:example(rbind),這時候console就會出現相關的訊息。
程式,或說是程式語言,名詞中既然既然已經有語言這個名詞出現,就表示這種語言基本上和一般中文、英文等語言一定有類似的地方。
像是以前學英文常說的英文有八大詞性,五大句型…..其實電腦程式語言也有類似的用法。
一個基本的程式,一般除了變數、資料之外 ,還有許多的指令來協助程式的完成。
簡單說,寫一個程式,其實和寫一段文章,或是一篇小說差不多。

Syntex:
if (condition_1){
#Do something here....
} else if (conditon_2){
#Do something here
} else {
#Do something here
}
Note: else if and else are optional.
ifelse(test_cond1, res_yes, res_no) 若test_cond1的條件成立(回傳是TRUE),則會執行res_yes的動作,否則test_cond1回傳是FALSE的話,則會執行res_no 例如
x = 7
ifelse(x>10, print("x大於10"), print("x小於10"))
## [1] "x小於10" ## [1] "x小於10"
一般情況下,如果向量中只有一個變數時,if()和ifelse()沒什麼差別, 但如果向量是一個多個數值的陣列array,矩陣matrix,或是list/data.frame時,這時候就很難用if來判斷了。 例如:
x = c(1:10)
if (x>5)
print("x>5")
## Warning in if (x > 5) print("x>5"): the condition has length > 1 and only
## the first element will be used
x = c(1:10) ifelse((x>5),TRUE,FALSE)
## [1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
小明得到媽媽的鼓勵和更多的糖果之後,就開開心心的去學校了。 上學途中,看到滿天飛舞的櫻花,不禁心頭一陣酸楚,之前拿到的糖果此時居然愈來愈重,吃了之後也不覺得甜美。 邊走邊想著:小時候喜歡的那個女孩,也是曾經在這種爛漫的的櫻花中,含著眼淚吞著鼻水的互相告別,不知道現在怎麼樣了? 對了,記得她是閏年出生的,那閏年的意義對她應該很重要吧。我們兩個人年紀都大了,已經不是3歲5歲的小孩了,我還能去找她嗎?還有機會嗎?還可以在一起嗎?
這時候,小明下定決心,想要認真的面對這段以前甜美,現在遺憾的回憶,打算在閏年的時候,鼓起勇氣去找她。 便在路旁的星巴八飲料店,拿出優雅的水果電腦,很快的在電腦上用R寫了一個判斷閏年的小工具。
原來如此。小明突然覺得自己很厲害
year1 = 2015 #或是可以用 as.integer(readline("input year:")),來輸入想要的數值
if ((year1 %% 4)==0){
if ((year1 %% 100)==0){
if ((year1 %% 400)==0)
print("Leap year")
else
print("Not leap year")
} else {
print("Leap year")
}
} else {
print("Not leap year")
}
## [1] "Not leap year"
year1 = 2015 #或是可以用 as.integer(readline("input year:")),來輸入想要的數值
if ( ((!(year1 %% 4)) && (year1 %%100)) || (!(year1 %% 400)) ){
print("Leap year")
} else {
print("Not leap year")
}
## [1] "Not leap year"
for() 迴圈簡單說就是某個動作重複做多少次,一般來說,需要明確的知道
小明又出現了,這次他帶著更多的遺憾,更多的苦澀,回到家裡。 可是,小明他自己知道,小明這個名字是以前國立編譯館,眾多國中國小出版社,PTT八卦版許多夢境中最常被拿出來用的名字, 「小明」這兩個字充滿著正面、希望、勇氣、努力,根本就是各種可能的代名詞。連小明的日文名字:Hikari或Akira,都是史詩巨作:棋靈王主角的名字。 「我不能如此放棄」,小明如此的對自己這麼說。
這麼想的小明,腦中開始的一連串的計劃了。首先,小明第一件要做的事情,毫無疑問的就是要知道,到底有多少年是閏年。
這時候路旁的小七便利店,突然360度翻了過來,瞬間變成一家星巴八飲料店的外觀, 小七店內突然傳出聲響:Change,仔細一看,小七店員身上的招牌紅色T-Shirt,居然也變成星巴八的白衣綠裙。
天時地利人和,小明毫不猶豫的,拿起手上的水果電腦,再次走進星巴八內,誓言如果沒辦法用R寫出計算閏年的程式的話就不出來。
除了上面的判斷是不是閏年之外,麻煩請在想一想,如何把一段時間內,例如從西元1000至西元2015年到底有多少年是閏年,分別為哪幾年?
提醒:可以用for來持續檢查某一年是否是閏年,例如:開始年:1000,結束年:2015
for(任意變數 in 開始:結束){ 打算要重複執行的程式 }
yearS = 1980 # 或是可以輸入:as.integer(readline("input start year:")) 來自己輸入開始年
yearE = 2100 # 或是可以輸入:as.integer(readline("input end year:")) 來輸入結束年
year_cnt=0
for (n in yearS:yearE){
if ( ((!(n %% 4)) && (n %%100)) || (!(n %% 400)) ){
year_cnt = c(year_cnt,n)
}
}
year_cnt = year_cnt[-1]
paste("total:", length(year_cnt)," leap years")
## [1] "total: 30 leap years"
is_leap_year = function(year1){
if (((!(year1 %% 4)) && (year1 %%100)) || (!(year1 %% 400)) ){ return(TRUE)
} else { return(FALSE) }
}
yearS = 1980 # 或是可以輸入:as.integer(readline("input start year:")) 來自己輸入開始年
yearE = 2100 # 或是可以輸入:as.integer(readline("input end year:")) 來輸入結束年
year_cnt=0
for (n in yearS:yearE){
if (is_leap_year(n)){
year_cnt = c(year_cnt,n)
#print("year:",n)
}
}
year_cnt = year_cnt[-1]
paste("total:", length(year_cnt)," leap years")
## [1] "total: 30 leap years"
Function,一般稱為函數,函式,或叫作方程式,簡單說就是把一堆為了相同目的的指令,用一個名稱綁在一起。
例如:
helloworld <- function(name1){
paste("Hello World,", name1)
}
helloworld("N")
## [1] "Hello World, N"
helloworld:就是函式名稱,之後要使用的話,直接在命令列上輸入helloworld()就可以了 name1:代表這個函式所帶入的參數,這邊取用name1當作參數的名字。
這個難度有點高,不過相信大家一定還是覺得小蛋糕一片才對。
https://zh.wikipedia.org/zh-tw/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F
步驟為:
+ 1. 從數列中挑出一個元素,稱為"基準"(pivot), + 2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。 + 在這個分割結束之後,該基準就處於數列的中間位置。這個稱為分割(partition)操作。 + 3. 遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。</div>遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。 雖然一直遞迴下去,但是這個演算法總會結束,因為在每次的疊代(iteration)中,它至少會把一個元素擺到它最後的位置去。
作為一個好好用,且知名度超高的統計軟體,其實R內建了許多好用的排序工具,像是 sort(), order(), rank(), 以下會簡略介紹使用方法
sort(): 會傳回一個已經排序列的數值向量。
x = sample.int(100,10) #sample是取亂數的函式,sample.int()強調整數的部份,100代表亂數會在100以內的數值,10則代表取10個數值 sort(x)
## [1] 8 39 47 50 51 52 57 64 75 89
order(): 會回傳在排序後,各個元素在原始的向量中(x)的排行的值(sorting後的index值)
x = sample.int(100,10) order(x)
## [1] 9 7 6 3 10 8 5 4 2 1
rank() : 會回傳排序前,各個元素在原始的向量中(x)的排行的值(sorting前的index值)
x = sample.int(100,10) rank(x)
## [1] 9 6 2 3 8 7 10 4 5 1
利用system.time()的函式,我們可以知道一個函數,或是一個程式的運算時間。 例如: 亂數產生一個矩陣: m1 = matrix(sample(25002000), 200) m1 = matrix(rnorm(25002000), 200) m1 = matrix(runif(25002000), 200) m1 = matrix(rgamma(25002000), 200)
計算不同的方法的排序時間快慢:
m1 = matrix(sample(2500*2000), 200) system.time(sort(m1))
## user system elapsed ## 0.844 0.017 0.878
"m1 = matrix(sample(2500*2000), 200) " "system.time(qsort(m1)) "
## [1] "m1 = matrix(sample(2500*2000), 200) " ## [1] "system.time(qsort(m1)) "
寫了一堆程式之後,人都可能被劈腿,手一定有機會出鎚,這時候就需要一些去除錯誤(簡稱:除錯)的工具來幫忙找到錯誤。
幸運的是,R內部就已經提供的debug() / undebug()的工具來一步一步,一行一行的找到問題。
遇到不知道怎麼使用的指令時,在console命令列中輸入?debug,變可以看到debug的說明。
或是想知道有沒有範例可以知道某個指令怎麼用?在console命令列中輸入example(指令),變可以看到該指令的應用
?debug
RBlogger的範例: http://www.r-bloggers.com/error-handling-in-r/
inputs = list(1, 2, 4, -5, 'oops', 0, 10)
for(input in inputs) {
print(paste("log of", input, "=", log(input)))
}
很明顯的,log的參數只能接受不能輸入負數的資料,而且文字資料一定出錯,那我們要怎麼避免?
inputs = list(1, 2, 4, -5, 'oops', 0, 10)
for(input in inputs) {
try(print(paste("log of", input, "=", log(input))))
}
## Warning in log(input): NaNs produced
## [1] "log of 1 = 0" ## [1] "log of 2 = 0.693147180559945" ## [1] "log of 4 = 1.38629436111989" ## [1] "log of -5 = NaN" ## [1] "log of 0 = -Inf" ## [1] "log of 10 = 2.30258509299405"
inputs = list(1, 2, 4, -5, 'oops', 0, 10)
for(input in inputs) {
tryCatch(print(paste("log of", input, "=", log(input))),
warning = function(w) {
print(paste("negative argument", input));
log(-input)
},
error = function(e) {
print(paste("non-numeric argument", input));
NaN})
}
## [1] "log of 1 = 0" ## [1] "log of 2 = 0.693147180559945" ## [1] "log of 4 = 1.38629436111989" ## [1] "negative argument -5" ## [1] "non-numeric argument oops" ## [1] "log of 0 = -Inf" ## [1] "log of 10 = 2.30258509299405"
summary(cars)
## speed dist ## Min. : 4.0 Min. : 2.00 ## 1st Qu.:12.0 1st Qu.: 26.00 ## Median :15.0 Median : 36.00 ## Mean :15.4 Mean : 42.98 ## 3rd Qu.:19.0 3rd Qu.: 56.00 ## Max. :25.0 Max. :120.00